Apple Location Manager
SDK 1.0.1

May 17, 1997

 

 

By Erik Sea - © 1996-1997, Apple Computer Inc.

(based on "Walkabout API" by Eric Slosser)

This document is designed to be viewed in a web browser, but also available as PDF;
as such, it is optimum for neither format, but tolerable in either.

Look for the ALM Developer page, coming soon to DevWorld!

Contents

Summary

The Apple Location Manager (ALM), version 1.0, was announced at MacWorld Expo in San Francisco on January 6, 1997 (see link at bottom for full text):

...

Apple Computer, Inc. today announced a free software utility for PowerBook computers called Apple Location Manager. Apple Location Manager software makes it easy for PowerBook users to move from one location to another without having to spend a lot of time manually reconfiguring their computer with every move.

"Mobile users, by definition, change location frequently. Apple Location Manager takes the difficulty out of moving from one place to another because with a single command, a user can reconfigure his or her system to the settings needed at any given location," said Dale Fuller, vice president and general manager for the PowerBook division. "It's a small piece of software, but it does a big job and saves people a lot of time and inconvenience. It's what Apple is all about...making complex tasks simple."

...

http://product.info.apple.com/pr/press.releases/1997/q2/970106.pr.rel.locmgr.html

As you may gather from the above excerpt, ALM provides a user interface for saving and restoring sets of settings so that PowerBook users can reconfigure their systems easily as they move from place to place.

Although ALM 1.0 ships with support for switching the default printer, TCP/IP settings, time zone, and a few other things, the ALM software is primarily an infrastructure for storing, retrieving, and applying sets of settings, and we expect third-party developers who are interested in meeting the needs of mobile users will be eager to use this framework to enhance their products, so we are providing this SDK.

Supporting ALM is not difficult - most of the time, you will not need to modify your product at all to add ALM support.

For most developers, "supporting" ALM means simply that - providing ALM with enough information to switch settings under user control in a way that is compatible with software that uses those settings. In addition to providing the infrastructure for making these changes, however, ALM also provides an API that developers can use to do a number of other things: applications can initiate switches, can request notification of switches while they are running, and can get information about user-defined sets of settings. These calls allow developer applications to become "location-aware" or they might be used to create "location-sensing" applications that could initiate switches automatically based on changes in the machine's environment.

Availability

Version 1.0 of ALM is available for download at the PowerBook Website, http://www.powerbook.apple.com/, where some third-party ALM efforts are also listed (there should be information at that site on how to get your stuff listed). This version runs only on 68030 or better PowerBooks (including all PowerPC PowerBooks) with System 7.6. For information on distributing any part of Apple Location Manager with your product, contact the Software Licensing Department: sw.license@apple.com. The evangelist for ALM is Doug MacMillan, standup@apple.com.

Version 1.0.1 of ALM is scheduled for inclusion in Mac OS 8, and its Apple Guide files will only work with Mac OS 8 (because it is a mixin guide).

Version 2.0, still early in development, should be available late in 1997. As announced at the WWDC hardware directions conference, ALM 2.0 will be enabled on desktop machines.

Acknowledgements

Many thanks to the entire ALM team for their tireless efforts in getting ALM into the hands of users and developers. Our collective thanks are also extended to third-party developers who participated in the seed program, without whose feedback and support ALM wouldn't be as useful nor as reliable as it is.

Go to: Top - Summary - Definitions - Installing- Generic - Module Needs - API - Future - Resources


Definitions

ALM - Apple Location Manager.

Apple Location Manager - software suite composed of (at least) three pieces: a System Extension providing the system software infrastructure to switch between locations; a Control Panel providing the user interface for defining settings associated with a location and allowing users to switch between locations; a Control Strip Module to allow the user to switch between locations easily.

Current Location - the last location switched to. A special state called "None (off)" (not considered to be a Location) signifies that ALM has been turned off.

Deferred Switch - where a switch is initiated by the user at boot, if not all module settings in the location support switching at boot time, the switch will be reattempted when the Finder is running.

Depth - amount of information a module stores; for example, the Extensions Manager module only stores the name of an extension set, since that allows the user to redefine the extension set without adjusting every module that uses it; the Generic module, on the other hand, stores everything about a specified preference file, which may not be desirable. Basically, if a piece of software supports some concept of "named sets" within itself, a module should go no deeper than that set name, but, if a preference format is "universal", the module should capture everything as a setting.

Export - an ALM and module function that allows the user to capture enough information to take a setting to another machine and use it (provided the other machine has the same software and modules installed). Modules that support export may need to gather additional information to enable the importer to be able to recreate the setting.

Foot - thing at the end of a leg; also the symbol for ALM (see also Walkabout); often mistaken for a Paramecium.

Import - take a location exported by ALM and make it available for use on this computer.

Location - any positive number of settings, given a name by the user.

Module - a piece of code that interfaces with the ALM application and provides several functions that ALM uses to capture and apply a setting; a given module might or might not have settings associated with a given location.

Paramecium - a tiny, single-celled creature thought to resemble a stylized human foot (or maybe a slipper).

Reboot flags - depending on what a module changes, it may require the machine to reboot, or it may not; these flags are set by a module to specify its requirements that can then be communicated to the user when a switch occurs.

Setting - variable-length information owned by a module, returned to and preserved by ALM, then sent by ALM back to a module to effect a location switch.

Switch - an event (normally driven by the user), during which the current location changes; all modules associated with the "switched-to" location are asked to apply the settings they had previously defined for that location.

Task - old, pre-1.0 name for a Module.

Walkabout - old name for ALM, more obviously associated with feet.

Widget - old, pre-1.0 name for a Module.

Go to: Top - Summary - Definitions - Installing- Generic - Module Needs - API - Future - Resources


Installing and Using ALM 1.0

Installation

Provided with this SDK are debug and non-debug versions of ALM for your use in testing and development. Note that you should have Macsbug installed if you plan to install the debug build, since it is almost certain to generate a user break. The debug build is, however, not restricted to running on PowerBooks, while the non-debug build will only run on PowerBooks.

Interestingly, if you install the debug build first, you will then be able to install the non-debug build on a non-PowerBook, but the software will not run. This feature is a side-effect of allowing ALM to install on future PowerBooks, and is not to be considered a bug since end users should not have access to the debug build.

What goes where

Although using the installer is recommended, you may be interested in knowing where various pieces are placed, so here is a list of the pieces in the 1.0.1f6 install:

:System Folder:Control Panels:Location Manager
:System Folder:Control Strip Modules:Location Manager
:System Folder:Extensions:Location Manager Extension
:System Folder:Extensions:Location Manager Guide Addtns
:System Folder:Extensions:Location Manager Modules:Auto-Open Item
:System Folder:Extensions:Location Manager Modules:Default Printer
:System Folder:Extensions:Location Manager Modules:Extensions Mgr
:System Folder:Extensions:Location Manager Modules:File Sharing
:System Folder:Extensions:Location Manager Modules:Network
:System Folder:Extensions:Location Manager Modules:Sound
:System Folder:Extensions:Location Manager Modules:TimeZone
:System Folder:Extensions:Location Manager Modules:Internet Access
:System Folder:Preferences:Location Manager Prefs:Locations:Sample

These are, of course, localized for different countries. If you write modules, and you want to simplify their installation, your installation software may want to check for the presence or absence of the "Location Manager Extension", which is a file of type 'AINI' with creator 'walk'. If you find this file, you can install a module in the subfolder whose name is given in the STR# 128 resource at index position 20. This information is not guaranteed to remain at that spot (and I apologize for not having it in a more obvious place), but may be useful nonetheless; I do promise that, if that file and string is found, it will be as described above. If you do not find the file or string, you will have to fall back to your own semantics to decide whether or where to install, possibly using gestalt.

Using ALM

Once you have installed and restarted, open the control panel and play with some settings. ALM has comprehensive Balloon Help and Apple Guide support for your reference.

Go to: Top - Summary - Definitions - Installing- Generic - Module Needs - API - Future - Resources


The Generic Module: Prototype a Module Fast

If you want to get a feel for how modules work, the SDK provides a sample module, which is compiled to "Generic" and can be used to create a custom module quickly for experimental purposes. We do not, however, recommend that you use this technique to create a "finished" module, particularly since the Generic module has not been heavily tested by any stretch of the imagination!

That said, a lot of what modules do is similar. The Generic module provided with this SDK can be quickly customized with your favorite resource editor to provide a working module for a wide range of software, under the assumption that the software maintains a preference file in its preferences folder. With these instructions, you could create a working module for software that follows the "preference file" model in about 10 minutes.

Before I describe the "customization", however, be aware that, as with most generic solutions, a module derived from Generic without material code changes is not going to be terribly efficient, both in speed and in memory use, and should not be considered the "preferred" means for supporting ALM. I encourage you to plan and design your own module, perhaps by modifying the Generic code itself.

With that said, also be aware that these instructions are "quick & dirty" - very little in the way of explanation is provided. So, make a copy of the Generic module, giving it an appropriate name. The Generic module is set up to store preferences for MicroSoft Word 5, and, although it is in a "working" state, there are some things that need to be tidied up, so if you'll go through that exercise, you'll have a good idea of how to customize the module for your own use.

    So, you can see how easy it is to customize a module for use in many cases. The next section describes how to actually code a module, either from scratch or using the Generic module's code as a starting point.

Go to: Top - Summary - Definitions - Installing- Generic - Module Needs - API - Future - Resources


Module Needs: What Modules Must Do

Now that you've seen what you can do just by modifying the compiled Generic module, I hope you'll consider implementing your own module by modifying the Sample code, which is only slightly more involved (you believe me, don't you?).

Debugging Modules

Since installing modules normally requires restarting the machine, we provide developers a "shortcut" you can use to simplify testing modules, known as "Launch Time Loading". If you install the debug build of ALM, remove the Extension from the Extensions folder (and restart so that the extension is not currently loaded), and move it and the ALM Control Panel into your development folder. Then you can install your modules in a "Location Manager Modules" subfolder (that is, a subfolder of the folder you have the Control Panel and Extension in) and, each time you run the ALM Control Panel, your module will be dynamically reregistered. A reboot is necessary when the Extension is installed because the modules are registered by the Component Manager only at startup time. Replacing a module with a newer version in this case doesn't work because the Component Manager tracks registered modules by file ID, and replacing the module file changes the file ID.

Component Technology

The Component Manager is documented extensively in Inside Macintosh: More Macintosh Toolbox, and much of the discussion there I will either assume or ignore. See also the discussion of the 'thng' resource in the earlier section. Only three items are defined in the Rez header "LocationManager.r". The component type is kALMComponentType ('walk' for those who prefer graphical resource creation). The only other field of interest in the 'thng' resource are the "manufacturer flags", two of which are currently used in ALM:

#define   kALMMultiplePerLocation     1 /* bit 0 */
#define   kALMDescriptionGetsStale    2 /* bit 1 */

Bit kALMMultiplePerLocation indicates that multiple instances of this module can be added to a location; this is how the Auto-Open Item is defined.

Bit kALMDescriptionGetsStale causes ALM to "re-query" a module, to get new descriptions more frequently. Usually, if the settings have not changed, ALM assumes the description has not changed either, but this may not be the case in some modules; for example, the Extensions Manager module is intelligent enough to report that the current extensions set has not changed if the user simply renamed it - the description would refer to the old name if this bit were not set.

All other bits are reserved.

One thing about the Component Manager I will reiterate here is that it is based on "single code resource" technology, and, as such there is one entry point, and the call type is specified by a selector. Negative selectors are defined by the Component Manager, and are used for component "Open" and "Close" calls, among others (see the sample code). Nonnegative selectors correspond to the ALM module API:

kALMGetCurrentSelect
kALMSetCurrentSelect
kALMCompareSettingSelect
kALMEditSettingSelect
kALMDescribeSettingsSelect
kALMDescribeErrorSelect
kALMImportExportSelect
kALMGetScriptInfoSelect
kALMGetInfoSelect

Also, in ALM, the convention is to set the "doAutoVersion" bit in the 'thng' resource. Otherwise, duplicate versions of your module may confuse the user, and potentially ALM itself.

You should be aware that, in order to reduce memory footprint, ALM does not keep modules around long, so you can expect modules to be opened and closed frequently - try to keep your module fast. Also, it is generally considered to be bad form to fail in component Open routine, so I suggest you defer most of your initialization to the first "real" call. Remember, if there is a problem, you want to be able to explain it to the user if at all possible, and that requires your component to open successfully.

Handling Global Data

ALM Component Manager-based calls come in two flavors: with global data passed as the first parameter, and without. The ALM header "LocationManager.k.h" provides a means for you do implement ALM calls either all one way, or all the other, using a combination of macros. Using these macros may help you transition your code if ALM were to be implemented using CFM. I recommend using the header in the following manner if you intend to pass global data using the Component Manager:

#define    ALM_BASENAME()
#define    ALM_GLOBALS()      Globals

#ifndef    __LOCATIONMANAGER_K__
#include   <LocationManager.k.h>
#endif     /* __LOCATIONMANAGER_K__ */

You would then define the Globals data type, and expect it as the first parameter to your routines. And if you don't want global data, simply remove the second line above.

If you prefer to use "real" global data, you're on your own - consult the documentation for your development environment for ideas and strategies.

Options to Boot

Some modules require rebooting for the changes to take effect. To assess the impact of such changes, the module API lets ALM know if a reboot is required. If switching to a location involves a module requiring a reboot, ALM offers the user the chance to reboot, shutdown, or continue working after all modules are completed. There a number of options; for the most part, modules will return kALMNoChange (in the event the switch-to setting is the same as the current setting), kALMAvailableNow (in the event no rebooting is required), or kALMExtensions (in the event extensions need to be reloaded; this implies a restart in the current OS).

kALMNoChange
kALMAvailableNow
kALMFinderRestart
kALMProcesses
kALMExtensions
kALMWarmBoot
kALMColdBoot
kALMShutdown

The API Itself

This is the moment you've been waiting for - the definitions for each of the nine API calls a module may support (some are optional). In the following, I will assume you've followed the recommendation given above, and defined ALM_BASENAME() to nothing, so that these will be your routines, as prototyped for you in LocationManager.k.h (shown in both non-global and global format). While this summary may be good for reference, to get a feel for the calls I suggest you refer to the sample and explore its functionality.

GetCurrent

pascal ComponentResult GetCurrent (Handle setting);
pascal ComponentResult GetCurrent (Globals globals, Handle setting);

When this call is made, the setting will already be allocated (but not the right size), so resize it as necessary; the format of your data is entirely private to you, and ALM simple stores the entire handle, whatever its size. Cast it to your private setting handle type and fill it with information describing whatever preferences your module cares about.

Return an error if the software you need isn't installed, or if the current setting suggests that the software isn't initialized (the Time Zone module, for example, returns an error if the current location has not been set.)

As stated previously, modules should Open even when the software the module works with isn't installed. You can then return an error from GetCurrent to tell the user what's wrong with the system.

SetCurrent

pascal ComponentResult SetCurrent (Handle setting, ALMRebootFlags* flags);
pascal ComponentResult SetCurrent (Globals globals, Handle setting,
                                  ALMRebootFlags* flags);

Set the current settings for your module; the setting passed in will be one previously returned to ALM on a GetCurrent call. Indicate via *flags what type of rebooting is necessary, if any.

CompareSetting

pascal ComponentResult CompareSetting (Handle setting1, Handle setting2,
                                  Boolean* equal);
pascal ComponentResult CompareSetting (Globals globals, Handle setting1,
                                  Handle setting2, Boolean* equal);

Compare the contents of two settings. ALM uses this to determine if the setting your module is responsible for has changed and requires an update. Updates are currently only done by the user in the ALM Control Panel, but future versions may allow the user to update at other times when a change is detected.

EditSetting

pascal ComponentResult EditSetting (Handle setting);
pascal ComponentResult EditSetting (Globals globals, Handle setting);

Interact with the user to modify the contents of the setting. Present whatever interface is necessary (launch your application, bring up your control panel, even show a movable modal in the ALM Control Panel's context). If you cause ALM to be put in the background, bring it to the foreground after the editing is done (this implies that you also need to know when editing is "done").

This call is currently optional; the Component Manager's "canDo" selector is used to determine if the module supports it or not. Although this call is optional, if you do not implement it, the user will be required to edit "live" settings to make changes, and then use the ALM Control Panel to update the setting; the user may find this confusing. We strongly encourage you to implement this call; future versions of ALM may require it, and your module might be disabled if it does not support EditSetting.

DescribeSettings

pascal ComponentResult DescribeSettings (Handle setting, StringHandle text);
pascal ComponentResult DescribeSettings (Globals globals, Handle setting,
                                  CharsHandle text);

Generate text which will be used in the location window to express what the setting represents. The description handle "text" will already be allocated. Resize it to fit the string you plan to return. The length of the text ALM displays is determined by the size of the description handle. The font information returned by GetScriptInfo will be used to display the text.

DescribeError

pascal ComponentResult DescribeError (OSErr lastErr, Str255 errStr);
pascal ComponentResult DescribeError (Globals globals, OSErr lastErr,
                                  Str255 errStr);

Generate a string which will be used in the location window (or the switch window) to describe an error. If you return paramErr, a generic routine will be used to describe the error. Make an attempt to describe the errors most likely to be returned by your various other routines. The technique Apple's modules use is to convert generic errors to specific ones; the Extensions Manager widget might translate certain instances of fnfErr (-43) to a private, positive number, which this routine might describe as "The Extensions Manager is not installed."

ImportExport

pascal ComponentResult ImportExport (Boolean import, Handle setting,
                                  short resRefNum);
pascal ComponentResult ImportExport (Globals globals, Boolean import,
                                  Handle setting, short resRefNum);

This call is optional, however, modules that support it need only store sufficient information in the handle returned to a GetCurrent to effect a SetCurrent call. Supporting modules will be asked to convert their setting to a "complete" only when the user imports or exports a location.

If a module supports this call, it may be useful to define a field in the setting to indicate whether it is in exported or local form, assuming the data is all to be stored in the handle still.

If it is not convenient to have two forms of setting handle, you can UseResFile (resRefNum), to use the resource fork of the current import/export file, and add additional data as resources. To avoid resource collisions, you use your module's component signature as a reserved resource type.

GetScriptInfo

pascal ComponentResult GetScriptInfo (ALMScriptMgrInfo* info);
pascal ComponentResult GetScriptInfo (Globals globals, ALMScriptMgrInfo* info);

This call gets information from the module that will allow ALM to display the various strings the module returns in the correctly localized script and region. Return the fields in accordance with how your module has been localized.

#pragma options align=mac68k

typedef struct {

SInt16          version;
SInt16          scriptCode;
SInt16          regionCode;
SInt16          langCode;
SInt16          fontNum;
SInt16          fontSize;

} ALMScriptMgrInfo;

#pragma options align=reset

Although this call is optional, it is recommended that you implement it, along the style provided in the sample code. If you do not implement it, ALM will assume the current environment, something like this:

version    = kALMScriptInfoVersion;
scriptCode = smSystemScript;
regionCode = GetScriptManagerVariable (smRegionCode);
langCode   = GetScriptVariable(smSystemScript,
                                  smScriptLang);
fontNum    = GetScriptVariable(smSystemScript,
                                  smScriptAppFond);
fontSize   = GetScriptVariable(smSystemScript,
                                  smScriptAppFondSize);

GetInfo

pascal ComponentResult GetInfo (StringHandle* text, STHandle* style,
                                  ModalFilterUPP filter);
pascal ComponentResult GetInfo (Globals globals, CharsHandle* text,
                                  STHandle* style, ModalFilterUPP filter);

This call is made when the user clicks the "Get Info" button in the location editing window.

It can return a text handle (and an optional style handle), or it can do its own thing, such as launching an external help system. The text will be displayed in a scrolling window.

Go to: Top - Summary - Definitions - Installing- Generic - Module Needs - API - Future - Resources


API: Driving ALM from Applications

Although ALM is, by itself, a fairly comprehensive software suite, it was recognized early in the design that if the framework were exposed, third-party developers could exploit some of ALM's internal workings to create customized solutions that we hadn't thought of. Also, during the development of modules, some common tasks began to emerge that we think other module developers would prefer not to reimplement.

In this SDK, you will find the header "LocationManager.h", interface "LocationManager.p" and even "LocationManager.a", if you are so inclined. If your project is PowerPC-based, you will need to link with the stub library LocationManagerLib. Weak linking is recommended; compare one of the seven exported routines against kUnresolvedCFragSymbolAddress (before calling any of them) to see if ALM is installed. Note that although the stub library does contain CFM-68K stubs, ALM 1.0 as currently distributed, including with this SDK, does not contain the corresponding CFM-68K implementation. For this reason, I recommend classic 68K development for now.

AppleScript

Although this is mentioned in the user's Read Me, if you prefer to speak AppleScript, it is possible to change the current location thusly:

   tell application "Finder"
     open file ((control panels folder
as string) & "Location Manager")
   
  tell application "Location Manager"
   
    set current location to location myLocationName
   
  end tell
   
end tell

If you see specific functionality that you think should be scripted, please use the bug reporter stack as described in Other Resources.

Determining if ALM is available

As with most things Mac, you should use gestalt to check for ALM (you do not need to do this in a module, since modules will only be called if ALM is around anyway, so checking would be somewhat redundant). Two gestalt selectors are defined: gestaltALMVers which returns the version of ALM installed in NumVersion format for your interest (get the pieces using the union NumVersionVariant.whole), and gestaltALMAttr which returns the attributes of ALM; you should test bit gestaltALMPresent to see if ALM is installed.

Managing Locations

Four routines are defined to let you examine the locations a user has defined.

pascal OSErr
ALMGetCurrentLocation(SInt16* index, ALMToken* token, Str31 name);

Gets three values describing the current location. Pass NULL for any value you don't want. Index is zero-based; in ALM 1.0, there can be at most 16 locations, so *index will never be more than 15, but this may change in future releases. If there is no current location, the *index will be returned as kALMNoLocationIndex, *token will be kALMNoLocationToken, and the name will be "None (off)", as localized. An ALMToken is a private ALM data structure reference.

pascal OSErr
ALMGetIndLocation(SInt16 index, ALMToken
* token, Str31 name);

Use this call to index through the defined locations, returning their tokens and names. Note that you can pass kALMNoLocationIndex to get the localized version of the "None (off)" state. This function will return paramErr if the index is out of range. Again, pass NULL for any value you don't want returned.

pascal OSErr
ALMCountLocations(SInt16
* nLocations);

Returns the number of locations defined.

pascal OSErr
ALMSwitchToLocation(ALMToken newLocation, SInt32 switchFlags);

Initiates a location switch. The switchFlags parameter is a set of flags that control switching options. Use kALMDefaultSwitchFlags for a normal switch or kALMDontShowStatusWindow for a "quiet" switch that does not put up the dialog box (not recommended).

If you are not sure about the environment in which you will be switching (for example, you are inside a background process, or inside a process that doesn't respond well to having a dialog suddenly popup inside its context), add the flag kALMSignalViaAE and the switch will be deferred until the Finder (or the Location Manager Control Panel) is the current process. The flag is so-named because the context is guaranteed by sending an AppleEvent since the Finder won't process an AppleEvent while it is not the current process!

Detecting Switches

ALM sends events to all AE-aware applications currently running whenever a switch occurs. The event has an AEEventClass of kAECoreSuite and an AEEventID of kAESystemConfigNotice. The event contains a parameter keyed under kAELocationNotice, which is a 32-bit quantity representing an ALMToken. If you are not an application (no, not you personally, but surely you view yourself as your code, right?), you can use the following routines to register a callback routine for notification:

pascal OSErr
ALMRegisterNotifyProc(ALMNotificationUPP notificationProc,
                    const ProcessSerialNumber
* whichPSN);

pascal OSErr
ALMRemoveNotifyProc(ALMNotificationUPP notificationProc,
                    const ProcessSerialNumber
* whichPSN);

You create an ALMNotificationUPP using the conventional myRoutineUPP = NewALMNotificationProc(MyALMNotificationRoutine), and dispose of it with DisposeRoutineDescriptor(myRoutineUPP). Your routine should conform to this interface:

pascal void
MyALMNotificationRoutine(AppleEvent
* theEvent);

Extract kAELocationNotice from theEvent in the same fashion as you would in an AEHandler.

Module Import Collisions

As discussed earlier, where preferences supported by a module keep track of named configurations, such as under Open Transport or Extensions Manager, the module should only keep track of the name of that configuration, until it needs to do an export. The problem becomes, then, that an Importing user might have a setting with the same name that is not the same setting. Obviously, it would not be good to blindly overwrite the existing setting. So, ALM provides the above call so that a module may prompt the user, without going through the general hassle of setting up a user interface within a code resource, for a new name (or to replace the old name).

pascal OSErr
ALMConfirmName(ConstStr255Param msg, Str255 configName,
                    SInt16* choice, ModalFilterUPP filter);

Typically, the module developer will call this routine with msg as a message indicating the conflict occurred. If a ^0 is embedded within the string, it will be replaced with the configName parameter for presentation to the user in the dialog (for example, if msg is "The config named "^0" exists." and configName is "MyConfig", the user sees a dialog with "The config named "MyConfig" exists."). If the user chooses to rename the config, the new name is returned in configName, and *choice is set to ALMConfirmRenameConfig; you should then check to see that the user hasn't collided with yet another config, possibly making this call again. If the user chooses to replace the config, you will get *choice of ALMConfirmReplaceConfig. The only other possibility is that the user cancels the whole operation, in which case the function returns userCanceledErr and *choice is not defined.

The final parameter, filter, is a standard dialog filter that you can use to filter events; set it to NULL otherwise. In ALM 1.0.x, the filter function is only called while the second dialog is up. This is a bug; future versions will call your filter function during both dialogs' tenure. If the refcon of the dialog is zero, you can presume you are being called from ALM 1.0.x; if it is nonzero, then you are under a later version of ALM.

Errors

Listed here for completeness; most of these are unremarkable, although note that a module that cannot switch at startup time should return ALMDeferSwitchErr if it cannot handle a SetCurrent call at boot time. Generally, modules should only return errors that can be translated into informative messages to users via the DescribeError call.

ALMInternalErr              = -30049
ALMLocationNotFound         = -30048
ALMNoSuchModuleErr          = -30047
ALMModuleCommunicationErr   = -30046
ALMDuplicateModuleErr       = -30045
ALMInstallationErr          = -30044
ALMDeferSwitchErr           = -30043

Go to: Top - Summary - Definitions - Installing- Generic - Module Needs - API - Future - Resources


Future Directions

Shared Library Model

ALM has a long genesis, and currently uses the Component Manager to implement modules. In keeping with Apple's Dynamic Linked Library Statement of direction, a future version of ALM is likely to support CFM (see http://devtools.apple.com/eto/ProductInfo/DLLdirectional.html ), but Component Manager modules will probably continue to be supported simultaneously for a period of time to protect users' investment in your software.

Use on the Desktop

As originally conceived, ALM was targeted at mobile users who move their computers from place to place and were faced with the unpleasant chore of switching settings in several different control panels every time they sat down; for this reason, version 1.0.x only runs on PowerBooks. Version 2.0 will also run on Desktop machines.

Name/UI Change

It is possible that ALM 2.0 will not refer to "Locations" or even be called "Apple Location Manager", since such a name does not convey sufficient meaning on desktop machines. In addition, the User Interface contemplated for ALM 2.0 is somewhat different from that of 1.0.x. For both of these reasons, it is advisable to avoid making reference to specifics of the name or UI that might be changed.

AppleGuide

As it stands now, there is no easy way to provide AppleGuide and have it "mixin" to the Mobility topic ALM uses. I therefore suggest that your ALM AppleGuide content be located within the guide for your product.

Rhapsody

At this writing, it is not clear exactly how ALM will fit in to Apple's next generation OS, since ALM evolved in System 7. It is likely that ALM will work in Rhapsody's backward-compatibility environment, but we would be interested in hearing from developers and users about how ALM or ALM technology might be used under "native" Rhapsody.

Inside Macintosh: Apple Location Manager

There shall be no such book.

Go to: Top - Summary - Definitions - Installing- Generic - Module Needs - API - Future - Resources


Other Resources

ALM Developers

Other companies have already written Location Manager modules:

Network TeleSystems, Inc. Location Manager Modules
The NTS PPP module 3.0 (free) allows switching of NTS PPP configurations. It requires NTS PPP version 3.0, which is available, free, on the Network Telesystems website. The NTS PPP module 4.0 (free) allows switching of TunnelBuilder and TCP Pro settings.

Prime Computing Solutions Location Manager Modules
Prime Computing has released two modules (shareware): one for OT/PPP and Modem settings, and one for MacPPP and FreePPP settings.

Reporting Bugs and Requests

If you find a problem or have a suggestion to make with respect to ALM or the SDK, please submit your report to devsupport@apple.com.

Reference Material

Techniques for Writing and Debugging Components, develop 12.

Component Manager, Inside Macintosh: More Macintosh Toolbox.

ALM article planned for an upcoming issue of develop. Date of publication not currently known.

Go to: Top - Summary - Definitions - Installing- Generic - Module Needs - API - Future - Resources